package com.yourenbang.lingyun.transaction.web.service.impl.pay.transaction;

import com.alibaba.fastjson.JSONObject;
import com.yourenbang.lingyun.constants.enums.PlatNoEnums;
import com.yourenbang.lingyun.constants.enums.pay.PayTypeEnum;
import com.yourenbang.lingyun.constants.enums.table.PayTransactionEnum;
import com.yourenbang.lingyun.core.util.KLog;
import com.yourenbang.lingyun.core.util.StringUtils;
import com.yourenbang.lingyun.core.util.date.DateFormat;
import com.yourenbang.lingyun.core.util.date.LocalDateUtils;
import com.yourenbang.lingyun.domain.Terminal21;
import com.yourenbang.lingyun.transaction.constant.LklTransTypeEnum;
import com.yourenbang.lingyun.transaction.web.domain.dto.yxy.LdysV2TradeDTO;
import com.yourenbang.lingyun.transaction.web.service.PayTransactionFormatService;
import com.yourenbang.terminal.api.service.RpcYxyTerminalService;
import com.yourenbang.transaction.api.model.vo.pay.PayTransaction;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.Map;
import java.util.Objects;

/**
 * @Description 联动优势交易格式化
 * @Date 20220808
 * @Created by Jason
 */
@Service
@Slf4j
public class LdysV2PayTransactionFormatServiceImpl implements PayTransactionFormatService {
    @Autowired
    private RpcYxyTerminalService rpcYxyTerminalService;

    /**
     * 13-特惠
     */
    private static final String TRADE_TYPE_TH = "13";
    /**
     * 14-特惠广发
     */
    private static final String TRADE_TYPE_TH_GF = "14";
    /**
     * 15-特惠平安
     */
    private static final String TRADE_TYPE_TH_PA = "15";
    /**
     * 16-特惠民生
     */
    private static final String TRADE_TYPE_TH_MS = "16";

    /**
     * 是对应的字符串
     */
    public static final String IS_TRUE = "01";

    @Override
    public PayTransaction payTransactionFormat(JSONObject jsonObject) {
        KLog.info("ldysV2格式化交易推送入参:{}", jsonObject.toJSONString());
        LdysV2TradeDTO ldysTradeDTO = jsonObject.toJavaObject(LdysV2TradeDTO.class);

        PayTransaction payTransaction = new PayTransaction();
        payTransaction.setMerchantNo(ldysTradeDTO.getMerchant_number());
        payTransaction.setMerchantName(ldysTradeDTO.getMerchant_name());
        payTransaction.setOrderNo(ldysTradeDTO.getTrade_number());
        payTransaction.setTransactionNo(ldysTradeDTO.getTrade_number());
        payTransaction.setTransactionAmount(new BigDecimal(ldysTradeDTO.getMoney()).divide(new BigDecimal("100")));
        if (StringUtils.isBlank(ldysTradeDTO.getFee())) {
            payTransaction.setTransactionFee(BigDecimal.ZERO);
        } else {
            payTransaction.setTransactionFee(new BigDecimal(ldysTradeDTO.getFee()).divide(new BigDecimal("100")));
        }
        payTransaction.setCardFlag(formatCardFlagLdys(ldysTradeDTO.getCard_type(), ldysTradeDTO.getTrade_type()));
        payTransaction.setRate(new BigDecimal(ldysTradeDTO.getFee_rate()).divide(new BigDecimal("100")).intValue());
        payTransaction.setTerminalId(ldysTradeDTO.getTerminal_number());
        payTransaction.setSn(ldysTradeDTO.getSn());
        payTransaction.setTransactionCardNo(ldysTradeDTO.getCard_no());
        payTransaction.setTransactionCardType(formatCardFlagLdys(ldysTradeDTO.getCard_type(), ldysTradeDTO.getTrade_type()));
        payTransaction.setStatus(formatTradeStatusLdys(ldysTradeDTO.getStatus()));
        LocalDateTime transTime = DateFormat.DATETIME_DEFAULT.parse(ldysTradeDTO.getTrade_time());

        payTransaction.setTransactionTime(transTime);
        payTransaction.setTransactionMonth(LocalDateUtils.localDateTimeByFormat(transTime, DateFormat.DATE_MONTH.getPartten()));
        payTransaction.setTransactionDay(LocalDateUtils.localDateTimeByFormat(transTime, DateFormat.DATE_COMPACT.getPartten()));
        //D0手续费
        if (StringUtils.isBlank(ldysTradeDTO.getFee_paid())) {
            payTransaction.setFeeAmt(BigDecimal.ZERO);
        } else {
            payTransaction.setFeeAmt(new BigDecimal(ldysTradeDTO.getFee_paid()).divide(new BigDecimal("100")));
        }
        //流量卡费金额
        BigDecimal noSettleAmt = BigDecimal.ZERO;
        if (StringUtils.isNotBlank(ldysTradeDTO.getTraffic_money())) {
            noSettleAmt = new BigDecimal(ldysTradeDTO.getTraffic_money()).divide(new BigDecimal("100"));
        }

        payTransaction.setAccAmt(payTransaction.getTransactionAmount().subtract(payTransaction.getTransactionFee())
                .subtract(payTransaction.getFeeAmt()).subtract(noSettleAmt));
        payTransaction.setWithdrawalStatus(PayTransactionEnum.WithdrawalStatusEnum.STATUS_40.getCode());

        Terminal21 terminal21 = rpcYxyTerminalService.getTerminalBySn(payTransaction.getSn());
        if (Objects.isNull(terminal21)) {
            return null;
        }
        payTransaction.setChannelId(terminal21.getChannelId());
        payTransaction.setPlatNo(PlatNoEnums.YXY.getCode());
        payTransaction.setIsDel(false);
        payTransaction.setTransType(formatPledgeStatusLdys(ldysTradeDTO.getIs_traffic(), ldysTradeDTO.getIs_deposit()));

        //分润标识
        payTransaction.setProfitFlag(checkIsProfitFlagLdys(payTransaction, ldysTradeDTO.getTrade_type()));
        //流量费
        if (StringUtils.equalsAny(ldysTradeDTO.getIs_traffic(), IS_TRUE) && StringUtils.isNotEmpty(ldysTradeDTO.getTraffic_money())) {
            payTransaction.setIccPayAmt(new BigDecimal(ldysTradeDTO.getTraffic_money()).divide(new BigDecimal("100")));
        }
        return payTransaction;
    }

    @Override
    public JSONObject dyUrlRequest(String uri, Map<String, Object> bodyJson) {
        return null;
    }

    @Override
    public JSONObject dyUrlRequestByPayType(String uri, Map<String, Object> bodyJson, PayTypeEnum payTypeEnum) {
        return null;
    }

    /**
     * ldys判断交易状态
     *
     * @param respCode
     * @return
     */
    private Short formatTradeStatusLdys(String respCode) {
        return PayTransactionEnum.TransactionStatus.STATUS_10.getCode();
    }

    /**
     * ldys判断押金状态
     * H007消费、Y007押金消费、S007流量卡交易
     *
     * @param isTraffic 收取流量卡费：01-收取、02-不收取
     * @param isDeposit 押金交易：01-是、02-否
     * @return 交易卡类型
     */
    private String formatPledgeStatusLdys(String isTraffic, String isDeposit) {
        if (StringUtils.equalsAny(isTraffic, IS_TRUE)) {
            return LklTransTypeEnum.TYPE_012003.getTransType();
        }
        if (StringUtils.equalsAny(isDeposit, IS_TRUE)) {
            return LklTransTypeEnum.TYPE_412001.getTransType();
        }
        return LklTransTypeEnum.TYPE_012001.getTransType();
    }

    /**
     * 联动优势判断交易卡类型
     *
     * @param cardType 卡类型：01-贷记卡、02-借记卡
     * @param payType  交易方式：01-刷卡、02-支付宝、03-微信、04-云闪付、13-特惠、14-特惠广发、15-特惠平安、16-特惠民生
     * @return 交易卡类型
     */
    private String formatCardFlagLdys(String cardType, String payType) {

        if (StringUtils.equals(payType, "03")) {
            return PayTransactionEnum.CardFlagEnum.WECHAT.getCode();
        }
        if (StringUtils.equals(payType, "02")) {
            return PayTransactionEnum.CardFlagEnum.ALIPAY.getCode();
        }
        if (StringUtils.equals(payType, "04")) {
            return PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode();
        }
        if (StringUtils.equals(cardType, "02")) {
            return PayTransactionEnum.CardFlagEnum.BORROW_CARD.getCode();
        }
        if (StringUtils.equalsIgnoreCase(cardType, "01")) {
            return PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode();
        }
        return cardType + "_" + payType;

    }

    /**
     * 判断是否计入分润
     * @param payTransaction PayTransaction
     * @param ldysTradeType ldysTradeType
     * @return  boolean
     */
    private boolean checkIsProfitFlagLdys(PayTransaction payTransaction, String ldysTradeType) {

        // 联动特惠民生交易不记分润
        if (StringUtils.equals(ldysTradeType, TRADE_TYPE_TH_MS)) {
            payTransaction.setRemarks("特惠民生");
            return false;
        }

        //贷记卡且非押金交易,非流量卡交易才计入分润
        if (StringUtils.equalsAny(payTransaction.getCardFlag(), PayTransactionEnum.CardFlagEnum.ALIPAY.getCode(),
                PayTransactionEnum.CardFlagEnum.WECHAT.getCode(),
                PayTransactionEnum.CardFlagEnum.CREDIT_CARD.getCode(),
                PayTransactionEnum.CardFlagEnum.UNIONCODE.getCode()) &&
                !StringUtils.equals(LklTransTypeEnum.TYPE_412001.getTransType(), payTransaction.getTransType())) {
            return true;
        }

        return false;
    }
}
